﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using OpenTelemetry;
using System;
using WorkFlowCore.Common.Tracers;

namespace WorkFlowCore.Host
{
    public static class OtelExtensions
    {
        public static IServiceCollection AddOtel(this IServiceCollection services)
        {
            services.AddLogging(logging =>
            {
                logging.AddOpenTelemetry(opt =>
                {
                    opt.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("WorkFlowCore.Host"));
                    // 日志级别过滤
                    opt.IncludeScopes = true;
                    opt.IncludeFormattedMessage = true;
                    opt.ParseStateValues = true;
                });
            });
            var otel = services.AddOpenTelemetry();

            // Add Metrics for ASP.NET Core and our custom metrics and export via OTLP
            otel.WithMetrics(metrics =>
            {
                metrics.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("WorkFlowCore.Host"));
                // Metrics provider from OpenTelemetry
                metrics.AddAspNetCoreInstrumentation();
                metrics.AddHttpClientInstrumentation();
                //Our custom metrics
                metrics.AddMeter(WorkflowActivitySource.SourceName);
                // Metrics provides by ASP.NET Core in .NET 8
                metrics.AddMeter("Microsoft.AspNetCore.Hosting");
                metrics.AddMeter("Microsoft.AspNetCore.Server.Kestrel");
            });

            // Add Tracing for ASP.NET Core and our custom ActivitySource and export via OTLP
            otel.WithTracing(tracing =>
            {
                tracing.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("WorkFlowCore.Host"));
                tracing.AddSource(WorkflowActivitySource.SourceName);
                tracing.AddAspNetCoreInstrumentation(opt =>
                {
                    opt.EnrichWithHttpRequest = (act, req) =>
                    {
                        if (string.IsNullOrEmpty(act.ParentId))
                        {
                            act.DisplayName = req.Path;
                        }
                    };
                    opt.Filter = context =>
                    {
                        return context.Request.Path.ToString().StartsWith("/api/");
                    };
                });
                tracing.AddHttpClientInstrumentation(opt =>
                {
                    opt.EnrichWithHttpWebRequest = (act, req) =>
                    {
                        act.DisplayName = req.RequestUri.AbsolutePath;
                    };
                    opt.EnrichWithHttpRequestMessage = (act, req) =>
                    {
                        act.DisplayName = req.RequestUri.AbsolutePath;
                    };

                });

#if DEBUG
                tracing.AddEntityFrameworkCoreInstrumentation(options =>
                {
                    options.SetDbStatementForText = true; // 将 SQL 文本设置为 db.statement 标签
                    options.EnrichWithIDbCommand = (activity, command) =>
                    {
                        // 添加自定义标签（例如数据库类型）
                        activity.SetTag("db.system", command.Connection?.Database ?? "unknown");
                    };
                });
                //tracing.AddConsoleExporter();//控制台输出
#endif
            });

            // Export OpenTelemetry data via OTLP, using env vars for the configuration

            // Export OpenTelemetry data via OTLP, using env vars for the configuration
            otel.UseOtlpExporter(OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf, new Uri("http://192.168.2.103:4318"));

            return services;
        }
    }
}
